package com.xieyingwangluo.yxpart.logic;

import com.alibaba.fastjson.JSON;
import com.xieyingwangluo.yxpart.bean.Result;
import com.xieyingwangluo.yxpart.bean.User2Black;
import com.xieyingwangluo.yxpart.ehcache.server.UserCache;
import com.xieyingwangluo.yxpart.entity.BlacklistModel;
import com.xieyingwangluo.yxpart.entity.UserInfoModel;
import com.xieyingwangluo.yxpart.entity.UserModel;
import com.xieyingwangluo.yxpart.service.BlacklistService;
import com.xieyingwangluo.yxpart.service.UserInfoService;
import com.xieyingwangluo.yxpart.service.UserService;
import com.xieyingwangluo.yxpart.utils.StringBuildUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;

@Component
@Slf4j
public class UserLogic {
    @Autowired
    private UserService userService;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private BlacklistService blacklistService;
    @Autowired
    private UserCache userCache;

    /**
     * 头像保存路径
     */
    public static final String WINDOWS_PROFILES_PATH = "D:/var/img/tomcat/yxpart/";
    public static final String LINUX_PROFILES_PATH = "/var/img/tomcat/yxpart/";

    //注册
    @Transactional
    @CacheEvict(value = "userACache", allEntries = true)
    public Result add(UserModel userModel) {
        Map<String, Object> map = new HashMap<>();
        userModel.setNoid(StringBuildUtils.buildUUID());
        //积分
        userModel.setIntg(600);
        //状态
        userModel.setState(1);
        //vip
        userModel.setVip(1);
        userModel.setHead_img("/var/img/tomcat/yxpart/img-head.jpg");

        if (userModel.getTel() != null || !"".equals(userModel.getTel())) {
            UserModel user = new UserModel();
            user.setTel(userModel.getTel());
            List<UserModel> list = userService.selT(user.getTel());
            if (list.size() > 0) {
                return Result.generate(1, "User already exists", null);
            }
        }
        int cnt = userService.add(userModel);
        if (cnt > 0) {
            UserInfoModel userInfoModel = new UserInfoModel();
            userInfoModel.setNoid(StringBuildUtils.buildUUID());
            userInfoModel.setName(userModel.getName());
            userInfoModel.setSex(0);//默认0男
            userInfoModel.setBirth("19710101");
            userInfoModel.setIdnumb("130000000000000000");//身份证号
            userInfoModel.setCounty("130000");
            userInfoModel.setAddress("石家庄市桥西区");
            userInfoModel.setHeight(160);
            userInfoModel.setWeight(50);
            userInfoModel.setQq("0000000000");
            userInfoModel.setEmail("0000000000@qq.com");
            userInfoModel.setInfo("超厉害的！");
            userInfoModel.setUser_id(userModel.getNoid());
            userInfoModel.setState(1);//未审核
            userInfoService.add(userInfoModel);
            map.put("userModel", userInfoModel.getNoid());
            map.put("userInfoModel", userInfoModel);
            log.info("注册普通用户，清除查询所有缓存" + JSON.toJSONString(userModel));
            return Result.generate(0, "Add success", map);
        }
        return Result.generate(1, "Add fail", null);
    }


    //登录
    @Cacheable(value = "userOCache", key = "#tel + '-'+ #pwd")
    public Result checklogin(HttpSession session,
                             String tel,
                             String pwd) {
        boolean flag = userCache.get(tel);
        if (flag) {
            return Result.generate(1, "用户已被锁定，请5分钟后登陆!", false);
        }
        List<UserModel> list = userService.selT(tel);
        boolean isLook = userCache.put(tel);
        if (!pwd.equals(list.iterator().next().getPwd())) {
            if (isLook) {
                return Result.generate(1, "连续输错5次密码，账号已被锁定", null);
            } else {
                return Result.generate(1, "密码错误，请重新输入!", null);
            }
        }
        Map<String, Object> map = new HashMap<>();
        UserModel userModel = userService.checklogin(tel, pwd);
        if (userModel != null) {
            session.setAttribute("user", userModel);
            map.put("User", userModel);
            map.put("Login", "普通用户");
            return Result.generate(0, "Login success", map);
        }
        return Result.generate(1, "Login fail", null);
    }

    //普通用户退出登录
    public Result outlogin(HttpSession session) {
        session.getAttribute("user");
        session.invalidate();
        return Result.generate(0, "Out success", null);
    }

    //更新普通用户密码
    @Caching(evict = {
            @CacheEvict(value = "userACache", allEntries = true),
            @CacheEvict(value = "userOCache", key = "#noid + '-'+ #pwd+'-'+#oldpwd")
    })
    public Result updPwd(String noid, String pwd, String oldpwd) {
        UserModel user = userService.getById(noid);

        if (oldpwd.equals(user.getPwd())) {
            int cnt = userService.updPwd(noid, pwd);
            return Result.generate(0, "Upd success", cnt);
        }
        return Result.generate(1, "Upd fail", null);

    }

    //更新用户
    @Caching(evict = {
            @CacheEvict(value = "userACache", allEntries = true),
            @CacheEvict(value = "userOCache", key = "#userModel.noid")
    })
    public Result update(UserModel userModel) {
        UserModel user = userService.getById(userModel.getNoid());
        if (userModel.getTel() != null) {
            if (user.getTel().equals(userModel.getTel())) {
                int cnt = userService.update(userModel);
                return Result.generate(0, "Upd success", cnt);
            } else {
                List<UserModel> list = userService.selT(userModel.getTel());
                if (list.size() == 0) {
                    int cnt = userService.update(userModel);
                    return Result.generate(0, "Upd success", cnt);
                }
            }
        }
        return Result.generate(1, "Upd fail", null);
    }

    //查询用户信息
    @Cacheable(value = "userOCache", key = "#noid")
    public Result getById(String noid) {
        UserModel userModel = userService.getById(noid);
        userModel.setPwd("");
        if (userModel != null) {
            log.info("查询demo，进行单个缓存" + JSON.toJSONString(noid));
            return Result.generate(0, "Select success", userModel);
        }
        return Result.generate(1, "Select fail", null);
    }

    //模糊查询所有用户
    @Cacheable(value = "userACache", key = "#userModel.noid + '-'+ #userModel.tel + '-'+ #userModel.name+'-'+#userModel.head_img+'-'+#userModel.intg+'-'+#userModel.state+'-'+#userModel.vip+'-'+#userModel.create_time")
    public Result selA(UserModel userModel) {
        if (userModel != null) {
            List<UserModel> userModelList = userService.selA(userModel);
            return Result.generate(0, "Select success", userModelList);
        }
        return Result.generate(1, "Select fail", null);
    }

    //设置用户头像
    @Transactional
    public Result updImg(MultipartFile newProfile, String noid) {
        // 根据Windows和Linux配置不同的头像保存路径
        String OSName = System.getProperty("os.name");
        String profilesPath = OSName.toLowerCase().startsWith("win") ? WINDOWS_PROFILES_PATH
                : LINUX_PROFILES_PATH;

        if (!newProfile.isEmpty()) {
            // 当前用户
            UserModel userModel = userService.getById(noid);
            String imgPathAndNameDB = userModel.getHead_img();
            // 默认以原来的头像名称为新头像的名称，这样可以直接替换掉文件夹中对应的旧头像
            String newProfileName = null;
            // 若头像名称不存在
            if (imgPathAndNameDB != null || imgPathAndNameDB.equals(newProfile.getOriginalFilename())) {
                newProfileName = profilesPath + System.currentTimeMillis() + newProfile.getOriginalFilename();
                // 路径存库
                userModel.setHead_img(newProfileName);
                userService.update(userModel);
            }
            // 磁盘保存
            BufferedOutputStream out = null;
            try {
                File folder = new File(profilesPath);
                if (!folder.exists())
                    folder.mkdirs();
                out = new BufferedOutputStream(new FileOutputStream(newProfileName));
                // 写入新文件
                out.write(newProfile.getBytes());
                out.flush();
            } catch (Exception e) {
                e.printStackTrace();
                return new Result(1, "设置头像失败", Boolean.FALSE);
            } finally {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return new Result(0, "设置头像成功", Boolean.TRUE);
        } else {
            return new Result(1, "设置头像失败", Boolean.FALSE);
        }
    }

    @Transactional
    @Caching(evict = {
            @CacheEvict(value = "userACache", allEntries = true),
            @CacheEvict(value = "userOCache", key = "#noid + '-'+ #state+'-'+#info")
    })
    public Result updS(String noid, int state, String info) {

        UserModel user = userService.getById(noid);
        if (state == 0) {
            int cnt = userService.updS(noid, state);
            if (cnt > 0) {
                List<BlacklistModel> list = blacklistService.getByTel(user.getTel());
                if (list.size() > 0) {
                    BlacklistModel black = blacklistService.getTel(user.getTel());
                    BlacklistModel blacklistModel = new BlacklistModel();
                    blacklistModel.setState(state);//状态(0违规，1未违规)
                    blacklistModel.setNoid(black.getNoid());
                    blacklistModel.setInfo(info);
                    blacklistService.upd(blacklistModel);
                    return Result.generate(0, "用户已被拉黑", cnt);
                }
                BlacklistModel black = new BlacklistModel();
                black.setNoid(StringBuildUtils.buildUUID());
                black.setInfo(info);
                black.setTel(user.getTel());
                black.setState(state);//状态(0违规，1未违规)
                blacklistService.add(black);
                return Result.generate(0, "用户拉黑成功", cnt);
            } else {
                return Result.generate(1, "用户拉黑失败", null);
            }
        } else {
            int cnt = userService.updS(noid, state);
            if (cnt > 0) {
                BlacklistModel black = blacklistService.getTel(user.getTel());
                if (black == null) {
                    return Result.generate(1, "用户未曾进行拉黑，不能取消拉黑", null);
                }
                BlacklistModel blacklistModel = new BlacklistModel();
                blacklistModel.setState(state);//状态(0违规，1未违规)
                blacklistModel.setNoid(black.getNoid());
                blacklistModel.setInfo(info);
                blacklistService.upd(blacklistModel);
                return Result.generate(0, "用户取消拉黑成功", cnt);
            } else {
                return Result.generate(1, "用户已取消拉黑失败", null);
            }
        }
    }

    @Cacheable(value = "userOCache", key = "#state + '-'+ #name")
    public Result selS(int state, String name) {
        if (name == null || name.equals("")) {
            List<UserModel> list = userService.selS(state);
            List<User2Black> listB = new ArrayList<>();
            for (Iterator iterator = list.iterator(); iterator.hasNext(); ) {
                UserModel u = (UserModel) iterator.next();
                User2Black user2Black = new User2Black(u);
                user2Black.setBlacklistModel(blacklistService.getTel(u.getTel()));
                listB.add(user2Black);
            }
            return Result.generate(0, "Select success", listB);
        } else {
            UserModel userModel = new UserModel();
            userModel.setName(name);
            userModel.setState(state);
            List<UserModel> list = userService.selName(userModel);
            List<User2Black> listB = new ArrayList<>();
            for (Iterator iterator = list.iterator(); iterator.hasNext(); ) {
                UserModel u = (UserModel) iterator.next();
                User2Black user2Black = new User2Black(u);
                user2Black.setBlacklistModel(blacklistService.getTel(u.getTel()));
                listB.add(user2Black);
            }
            return Result.generate(0, "Select success", listB);
        }
    }
}
